#ifndef __CORE_SPHERE_H__
#define __CORE_SPHERE_H__

#include "CoreDefine.h"
#include "Vector3.h"

namespace Core
{
	class rtPlane;
	class rtRotation;

	class rtSphere
	{
	public:
		rtSphere(void);
		explicit rtSphere(const rtVector3& point);
		explicit rtSphere(const rtVector3& point, const float r);

		float			  operator [] (const int index) const;
		float& 			  operator [] (const int index);
		rtSphere		  operator + (const rtVector3& t) const;
		rtSphere& 		  operator += (const rtVector3& t);
		rtSphere		  operator + (const rtSphere& s) const;
		rtSphere& 		  operator += (const rtSphere& s);

		bool			  compare(const rtSphere& a) const;
		bool			  compare(const rtSphere& a, const float epsilon) const;
		bool			  operator == (const rtSphere& a) const;
		bool			  operator != (const rtSphere& a) const;

		void			  clear(void);
		void			  zero(void);
		void			  setOrigin(const rtVector3& o);
		void			  setRadius(const float r);

		const rtVector3&  getOrigin(void) const;
		float			  getRadius(void) const;
		bool			  isCleared(void) const;

		bool			  addPoint(const rtVector3& p);
		bool			  addSphere(const rtSphere& s);
		rtSphere		  expand(const float d) const;
		rtSphere& 		  expandSelf(const float d);
		rtSphere		  translate(const rtVector3& translation) const;
		rtSphere& 		  translateSelf(const rtVector3& translation);

		float			  planeDistance(const rtPlane& plane) const;
		int				  planeSide(const rtPlane& plane, const float epsilon = ON_EPSILON) const;

		bool			  containsPoint(const rtVector3& p) const;
		bool			  intersectsSphere(const rtSphere& s) const;
		bool			  lineIntersection(const rtVector3& start, const rtVector3& end) const;

		bool			  rayIntersection(const rtVector3& start, const rtVector3& dir, float& scale1, float& scale2) const;

		void			  fromPoints(const rtVector3 *points, const int numPoints);
		
		void			  fromPointTranslation(const rtVector3& point, const rtVector3& translation);
		void			  fromSphereTranslation(const rtSphere& sphere, const rtVector3& start, const rtVector3& translation);
		
		void			  fromPointRotation(const rtVector3& point, const rtRotation& rotation);
		void			  fromSphereRotation(const rtSphere& sphere, const rtVector3& start, const rtRotation& rotation);

		void			  axisProjection(const rtVector3& dir, float& min, float& max) const;

	private:
		rtVector3		m_Origin;
		float			m_Radius;
	};
}
#endif


